
#include "./overall.hpp"

#include <qlib/all.h>
#include <entt/entt.hpp>

#include <geos/geom/Coordinate.h>
#include <geos/geom/Envelope.h>
#include <geos/geom/Geometry.h>
#include <geos/geom/GeometryFactory.h>
#include <geos/geom/Point.h>
#include <geos/index/strtree/TemplateSTRtree.h>
#include <geos/io/WKTReader.h>
#include <geos/io/WKTWriter.h>
#include <spdlog/spdlog.h>

#include "../ecs/ecs.hpp"
#include "../layer/layer.hpp"
#include "../layout/layout.hpp"
#include "./events.hpp"
#include "./models.hpp"
#include "./select_cmd.hpp"

// namespace qbe::layout{
// }

namespace qbe::select {
struct OverallModel;

void overall_update(entt::registry& reg, ecs::Bus bus, ecs::Commands commands, ecs::Query query) {

  auto& state = query.get_resource<state::State>();

  auto& handle = query.get_resource<vsg::ref_ptr<input::HandleBundle>>();
  auto& axis = query.get_resource<axis::Axis>();
  auto& cell = query.get_resource<qlib::Cell::s_ptr>();
  auto& model = query.get_resource<OverallModel>();
  model.cell = cell;
  // auto& part_model = query.get_resource<SelectPartModel>();
  auto& layout_cmd = query.get_resource<layout::LayoutCmd>();
  auto& select_cmd = query.get_resource<SelectCmd>();
  auto& event_writer = query.get_event_writer<select::Event>();
  auto& layer_manager = query.get_resource<layer::Manager>();
  // auto& layers = layer_manager.layers;

  // 鼠标查询范围
  auto r = 30 / axis.scale;
  select_cmd.set_mouse_range(r);

  bool run_hover = false;
  bool run_one = false;
  bool run_all = false;
  bool run_box = false;

  bool run_overall = true;  // 默认开启
  bool run_part = false;

  bool run_order = false;
  bool run_multi = false;
  bool run_multi_cancel = false;
  bool run_draw_box = false;

  bool enable_part_edge = true;
  bool enable_part_point = true;
  bool enable_part_ref = true;

  // 其他模式过滤使用
  bool edit_mode_move = false;
  bool edit_mode_point_algin = false;
  bool edit_mode_line_algin = false;
  bool edit_mode_center_line = false;

  auto edit_mode = state.getEditingMode();
  auto draw_mode = state.getDrawingMode();
  auto edit_child_mode = state.getEditingChildMode();

  if (handle->keyPressed(vsg::KEY_Shift_L) || handle->keyPressed(vsg::KEY_Shift_R)) {
    model.key_shift_press = true;
    SPDLOG_INFO("key_shift_press : {}", true);
  }
  if (handle->keyReleased(vsg::KEY_Shift_L) || handle->keyReleased(vsg::KEY_Shift_R)) {
    SPDLOG_INFO("key_shift_press : {}", false);
    model.key_shift_press = false;
  }

  if (handle->keyPressed(vsg::KEY_Control_L) || handle->keyPressed(vsg::KEY_Control_R)) {
    SPDLOG_INFO("key_ctrl_press : {}", true);
    model.key_ctrl_press = true;
  }

  if (handle->keyReleased(vsg::KEY_Control_L) || handle->keyReleased(vsg::KEY_Control_R)) {
    SPDLOG_INFO("key_ctrl_press : {}", false);
    model.key_ctrl_press = false;
  }

  if (state.getSelectMode() == state::SelectModeType::None) {
    if (model.mode != 0) {
      model.mode = 0;
      select_cmd.clear_all();
      return;
    }
  }

  if (state.getSelectMode() == state::SelectModeType::Part) {
    if (model.mode != 1) {
      model.mode = 1;
      select_cmd.clear_all();
      return;
    }
    run_part = true;
  }

  if (state.getSelectMode() == state::SelectModeType::Overall) {
    if (model.mode != 2) {
      model.mode = 2;
      select_cmd.clear_all();
      return;
    }
  }

  if (edit_mode == state::EditingModeType::Rotation)
    return;

  if (edit_mode == state::EditingModeType::Affix)
    return;

  if (edit_mode == state::EditingModeType::CenterLine)
    return;

  if (edit_mode == state::EditingModeType::QuickAlign)
    return;

  if (edit_mode == state::EditingModeType::AutoRouteFixedDistanceStretchLine)
    return;

  if (edit_mode == state::EditingModeType::AutoRoutePushLine)
    return;

  if (edit_mode == state::EditingModeType::AutoRouteStretchLine)
    return;

  if (edit_mode == state::EditingModeType::AutoRouteTrendLine)
    return;
  if (edit_mode == state::EditingModeType::AutoRouteMultLine)
    return;

  if (edit_mode == state::EditingModeType::ConfirmLineLength)
    return;
  if (edit_mode == state::EditingModeType::LineAddCorner)
    return;
  if (edit_mode == state::EditingModeType::FilletTool)
    return;
  if (edit_mode == state::EditingModeType::AutoRouteNetlist)
    return;

  if (draw_mode != state::DrawingModeType::None) {
    return;
  }

  if (edit_mode == state::EditingModeType::Extension)
    return;

  if (edit_mode == state::EditingModeType::Clipping)
    return;

  if (edit_mode == state::EditingModeType::Decompose)
    return;

  if (edit_mode == state::EditingModeType::Drift)
    return;

  model.edit_mode = edit_mode;
  model.edit_child_mode = edit_child_mode;

  model.mode_change = true;

  input::KeyBoardShortcuts kbs;
  kbs.keyBase = vsg::KEY_a;
  kbs.keyModifier = vsg::MODKEY_Control;

  // if (handle->keyReleased(kbs)) {
  //   run_all = true;
  // }
  if (getKeyPressed("edit", "select all", bus)) {
    run_all = true;
  }

  auto cancel_drawing = bus.receive<qbe::UiMessage::CancelDrawing>();
  if (!cancel_drawing.empty()) {
    select_cmd.clear_all();
    return;
  }
  // if (handle->keyReleased(vsg::KEY_Escape)) {
  //   select_cmd.clear_all();
  //   return;
  // }

  if (handle->mousePressed(vsg::ButtonMask::BUTTON_MASK_1)) {
    model.mouse_move = false;
    model.box_exist = false;
    model.is_move_flag = false;

    // 绘制模式下，鼠标按下，清除选择
    if (draw_mode != state::DrawingModeType::None) {
      model.clear_select();
    }
    // run_hover = true;
    model.mouse_press = true;
    model.mouse_press_x = axis.real_x;
    model.mouse_press_y = axis.real_y;
    SPDLOG_INFO("[overall] mouse_press: {}", model.mouse_press);

    model.is_move_flag = select_cmd.hover_is_select() || select_cmd.hover_is_select_part();
  }

  if (handle->mouse_move) {
    run_hover = true;
    // 移动重置选择顺序
    model.order_reset();

    // 鼠标按下后移动
    if (model.mouse_press) {
      // 鼠标按下后移动，关闭预选
      run_hover = false;

      model.mouse_move = true;
      run_draw_box = true;

      SPDLOG_INFO("[overall] run_draw_box: {}", run_draw_box);
      // 运行移动
      if (model.is_move_flag) {
        run_draw_box = false;
      }
    }
  }

  if (handle->mouseReleased(1)) {
    SPDLOG_INFO("[overall] mouse_press: {}", model.mouse_press);
    // 单选开启：鼠标按下后没有移动
    if (model.mouse_press && !model.mouse_move) {
      // if (model.order_exist)
      run_order = true;
      run_one = true;
    }

    // 存在box，框选
    if (model.box_exist) {
      run_box = true;
      // 关闭绘制框
      run_draw_box = false;
      event_writer.send({{Code::DrawBoxCancel}});
    }

    // 清除鼠标事件
    if (model.mouse_press)
      model.mouse_press = false;
    if (model.mouse_move)
      model.mouse_move = false;
    if (model.box_exist)
      model.box_exist = false;
    if (model.is_move_flag)
      model.is_move_flag = false;
  }
  if (!model.enable_hover)
    run_hover = false;
  if (!model.enable_one)
    run_one = false;
  if (!model.enable_all)
    run_all = false;
  if (!model.enable_multi)
    run_multi = false;
  if (!model.enable_multi) {
    model.key_shift_press = false;
    model.key_ctrl_press = false;
  }

  model.edit_mode = edit_mode;
  model.edit_child_mode = edit_child_mode;

  model.mode_change = true;

  // 框选
  if (!model.enable_box)
    run_box = false;

  // 多选
  if (model.key_shift_press) {
    run_multi = true;
  }

  // 多选-取消
  if (model.key_ctrl_press) {
    run_multi_cancel = true;
  }

  if (run_box)
    model.op_type = OverallOperatorType::Box;

  if (run_all)
    model.op_type = OverallOperatorType::All;

  if (run_one)
    model.op_type = OverallOperatorType::One;

  if (run_multi)
    model.op_type = OverallOperatorType::Multi;

  auto& x = axis.real_x;
  auto& y = axis.real_y;

  std::tuple<qlib::Path::s_ptr, qlib::Polygon::s_ptr, qlib::Rectangle::s_ptr, qlib::Circle::s_ptr, qlib::Ellipse::s_ptr, qlib::Fan::s_ptr,
             qlib::Text::s_ptr, qlib::Label::s_ptr, qlib::Pin::s_ptr, qlib::KeyPoint::s_ptr>
      geo_types;

  // 顺序选择
  if (run_order) {
    // 边框选择顺序切换
    std::vector<entt::entity> orders = {};
    for (auto& [d, e] : model.order_borders) {
      orders.push_back(e);
    }

    if (orders.size() > 0) {
      for (uint32_t i = 0; i < orders.size(); i++) {
        // SPDLOG_INFO("e: {}, d: {:.3f}, order_cnt: {}, n: {}", uint32_t(e), d, model.order_cnt, n);
        if (i == model.order_cnt) {
          model.hover_entity = orders[i];
          select_cmd.clear_hover();
          select_cmd.add_hovers(std::vector<entt::entity>{orders[(i + 1) % orders.size()]});
          break;
        }
      }
      model.order_cnt += 1;
      if (model.order_cnt >= model.order_borders.size()) {
        model.order_cnt = 0;
      }
    }
  }

  if (run_hover) {
    bool is_find_part = false;
    // 部分选择
    if (run_part) {
      select_cmd.clear_hover_parts();
      std::unordered_map<entt::entity, SelectPartData> parts;
      is_find_part = select_cmd.get_part(x, y, parts, false);
      if (is_find_part) {
        select_cmd.add_hover_parts(parts, true);
      }
    }

    // 全选
    if (run_overall) {
      model.hover_entity = entt::null;
      select_cmd.clear_hover();
      if (!is_find_part) {
        // 按照轮廓、区域筛选
        select_cmd.get_select(x, y, model.order_borders);
        if (model.order_borders.size() > 0) {
          model.order_exist = true;
        }
        // 优先选择边框对象
        if (model.order_borders.size() > 0) {
          auto it_begin = model.order_borders.begin();
          model.hover_entity = it_begin->second;
        }
        select_cmd.add_hovers(std::vector<entt::entity>{model.hover_entity});
      }
    }
  }

  if (run_one) {
    bool is_order = true;
    if (!run_multi) {
      select_cmd.clear_select_order();
    }

    std::vector<entt::entity> e_arr;
    std::unordered_map<entt::entity, SelectPartData> select_parts;
    auto select_view = cell->reg.view<SelectTag>();
    bool hover_part_ok = false;

    // 部分选择 存在预选
    if (run_part) {
      auto hover_parts = select_cmd.hover_parts();
      for (auto& [e, part] : hover_parts) {
        // 确保对象没有被删除
        auto geo_exist = cell->try_gets(e, qlib::GeoPtrTypes());
        if (geo_exist) {
          hover_part_ok = true;
          // 筛选是否为全选
          if (run_multi) {
            // 多选
            if (!select_view.contains(e)) {
              select_cmd.add_select_parts(hover_parts, true);
            }
          } else if (run_multi_cancel) {
            // 取消选择
            auto overall_parts = hover_parts;
            if (select_view.contains(e)) {
              select_cmd.overall_parts(overall_parts);
              select_cmd.add_select_parts(overall_parts, true);
              select_cmd.remove_select(e);
            }
            select_cmd.remove_select_parts(hover_parts, true);
          } else {
            select_cmd.clear_select_parts();
            select_cmd.clear_select();
            select_cmd.add_select_parts(hover_parts, true);
          }

          // 检测对象的选中的部分是否包含对象部分的所有点，包含，标记对象为全选
          auto select_parts = select_cmd.select_parts();
          if (select_cmd.is_overall_part(e, select_parts[e])) {
            // e_arr.push_back(e);
            select_cmd.add_select(e);
            if (run_multi)
              select_cmd.add_select_order(e);  // 添加选择顺序
            select_cmd.remove_select_part(e);
          }

          // // 检测对象的选中的部分是否包含对象部分的所有点，包含，标记对象为全选
          // std::vector<entt::entity> remove_e_arr;
          // for (auto& [e, _n] : hover_parts) {
          //   auto& part = select_parts[e];
          //   if (select_cmd.is_overall_part(e, part)) {
          //     e_arr.push_back(e);
          //     remove_e_arr.push_back(e);
          //   }
          // }
          // select_cmd.remove_select_parts(remove_e_arr);
        }
      }
      if (hover_parts.size() == 0) {
        // 没有预选对象
        if (!run_multi && !run_multi_cancel) {
          select_cmd.clear_select_parts();
        }
      }
    }

    if (run_overall && !hover_part_ok) {
      if (model.hover_entity != entt::null) {
        auto e = model.hover_entity;
        // 确保对象没有被删除
        auto geo_exist = cell->try_gets(e, qlib::GeoPtrTypes());
        if (geo_exist) {
          if (run_multi) {
            // 多选
            // e_arr.push_back(e);
            select_cmd.add_select(e);
            select_cmd.add_select_order(e);    // 添加选择顺序
            select_cmd.remove_select_part(e);  // 删除对象部分选择
          } else if (run_multi_cancel) {
            // 取消选择
            select_cmd.remove_select(e);
          } else {
            // 单选
            select_cmd.clear_select();
            select_cmd.add_select(e);
            select_cmd.remove_select_part(e);
            // e_arr.push_back(e);
          }
        }
      } else {
        // 没有预选对象
        if (!run_multi && !run_multi_cancel) {
          select_cmd.clear_select();
        }
      }

      // if (e_arr.size() > 0) {
      //   // 选中对象去除部分选择
      //   for (auto& e : e_arr) {
      //     select_cmd.remove_select_parts(e_arr);
      //   }
      //   select_cmd.add_selects(e_arr);
      // }
    }
  }

  if (run_box) {
    std::vector<entt::entity> selects;
    auto& rect = model.box_rect;
    std::unordered_map<entt::entity, SelectPartData> parts;

    if (run_overall && !run_part) {
      select_cmd.get_box_select(rect->pos.x, rect->pos.y, rect->width, rect->height, selects, model.box_direct);
    }
    if (run_part) {
      select_cmd.get_box_part(rect->pos.x, rect->pos.y, rect->width, rect->height, selects, parts, model.box_direct, run_overall);
      auto select_view = cell->reg.view<SelectTag>();
      if (run_multi) {
        // 筛选已经选择的对象
        std::vector<entt::entity> remove_e_arr;
        for (auto& [e, _n] : parts) {
          if (select_view.contains(e)) {
            remove_e_arr.push_back(e);
          }
        }
        for (auto& e : remove_e_arr) {
          parts.erase(e);
        }
        // 多选
        select_cmd.add_select_parts(parts, true);
      } else if (run_multi_cancel) {
        // 筛选全选对象
        std::unordered_map<entt::entity, SelectPartData> t_parts;
        for (auto& [e, part] : parts) {
          t_parts[e] = part;
          if (select_view.contains(e)) {
            select_cmd.overall_parts(t_parts);
            select_cmd.add_select_parts(t_parts, true);
            select_cmd.remove_select(e);
          }
          t_parts.clear();
        }
        // 取消
        select_cmd.remove_select_parts(parts, true);
      } else {
        // 单选
        select_cmd.clear_select_parts();
        select_cmd.add_select_parts(parts, true);
      }

      // 检测对象的选中的部分是否包含对象部分的所有点，包含，标记对象为全选
      std::vector<entt::entity> e_arr;
      select_cmd.filter_select_parts(select_cmd.select_parts(), e_arr);
      select_cmd.remove_select_parts(e_arr);

      selects.insert(selects.end(), e_arr.begin(), e_arr.end());
    }

    // 全选
    if (run_overall) {
      if (run_multi) {
        // 多选
        select_cmd.add_selects(selects);
      } else if (run_multi_cancel) {
        // 取消选择
        select_cmd.remove_selects(selects);
      } else {
        // 单选
        select_cmd.clear_select();
        select_cmd.add_selects(selects);
      }
    }

    // select_cmd.remove_select_parts(selects);
  }

  if (run_all) {
    model.op_type = OverallOperatorType::All;
    // 遍历所有实体, 添加选择标记
    for (auto [e, tag] : cell->reg.view<qlib::Tag>().each()) {
      cell->reg.emplace_or_replace<SelectTag>(e);
    }
    for (auto [e, ref] : cell->reg.view<qlib::Reference::s_ptr>().each()) {
      cell->reg.emplace_or_replace<SelectTag>(e);
    }
    // // 遍历所有实体, 添加选择标记
    // for (auto e : cell->reg.view<entt::entity>()) {
    //   cell->reg.emplace_or_replace<SelectTag>(e);
    // }
    event_writer.send({{Code::SelectUpdate}});
  }

  if (run_draw_box) {
    SPDLOG_INFO(">>run_draw_box");
    auto& x = axis.real_x;
    auto& y = axis.real_y;
    if (!model.box_exist) {
      // 创建框选对象
      model.box_rect = qlib::Rectangle::create(qlib::Vec2d{axis.real_x, axis.real_y}, 0.0, 0.0);
      model.box_exist = true;
    }
    // 更新绘制的box
    if (model.box_exist) {
      auto& rect = model.box_rect;
      double w = x - model.mouse_press_x;
      double h = y - model.mouse_press_y;
      rect->pos.x = model.mouse_press_x;
      rect->pos.y = model.mouse_press_y;
      if (w < 0) {
        rect->pos.x = model.mouse_press_x + w;
        model.box_direct = DrawBoxDirect::Left;
      } else {
        model.box_direct = DrawBoxDirect::Right;
      }
      if (h < 0) {
        rect->pos.y = model.mouse_press_y + h;
      }
      rect->width = std::abs(w);
      rect->height = std::abs(h);
      // 更新box的mesh
      model.box_mesh = render::BoxMesh(rect->bounding_box());
      event_writer.send({{Code::DrawBoxUpdate}});
    }
  }
}

// void select_one(entt::registry& reg, ecs::Commands commands, ecs::Query query) {}

}  // namespace qbe::select